﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using FA.Library.Plugin;
using FA.Library.Sim.Events;
using FA.Library.ExtensionMethods;
using FA.Library.Sim;
using FA.Library.Sim.Aircraft;

namespace FA.Plugins.MockPlugin.Plugin
{
    /// <summary>
    /// This plugin mocks the core behaviour of the IPlugin interface. It is
    /// used for testing plugin loading and management.
    /// </summary>
    public class MockPlugin : IPlugin
    {
        public event EventHandler Disposed;
        public event EventHandler OnPluginStartEvent;
        public event EventHandler OnPluginStopEvent;
        public event EventHandler OnPluginSettingsChangedEvent;
        public event SimMessageEvent OnSimMessageEvent;
        public event SimExceptionEvent OnSimExceptionEvent;
        public event SimAircraftModelChangedEvent OnSimAircraftModelChangedEvent;

        public string Name { get; set; }
        
        public AircraftModel AircraftModel
        {
            get
            {
                return (_aircraftModel != null) ? (AircraftModel)_aircraftModel.Clone() : null;
            }
        }
        private AircraftModel _aircraftModel = null;

        public bool IsRunning
        {
            get { return _isRunning; }
            private set
            {
                if (_isRunning != value)
                {
                    _isRunning = value;

                    if (_isRunning && OnPluginStartEvent != null)
                        OnPluginStartEvent(this, null);
                    else if (!_isRunning && OnPluginStopEvent != null)
                        OnPluginStopEvent(this, null);
                }
            }
        }
        private bool _isRunning;

        public bool IsDisposed { get; private set; }

        private Dictionary<string, string> _settings = new Dictionary<string, string>();

        public MockPlugin()
        {
            IsDisposed = false;
            IsRunning = false;
        }

        /// <summary>
        /// Initialise the plugin.
        /// </summary>
        /// <param name="host"></param>
        public void Initialise()
        {
        }

        /// <summary>
        /// Dispose the plugin.
        /// </summary>
        public void Dispose()
        {
            if (IsDisposed)
                return;

            IsRunning = false;
            IsDisposed = true;
            if (Disposed != null)
                Disposed(this, null);
        }

        public void Start()
        {
            IsRunning = true;
        }

        public void Stop()
        {
            IsRunning = false;
        }

        public void UpdateSettings(Dictionary<string, string> settings)
        {
            if (settings == null)
                settings = new Dictionary<string, string>();

            if (!_settings.CheckForEquality<string, string>(settings))
            {
                _settings = settings;

                if (OnPluginSettingsChangedEvent != null)
                    OnPluginSettingsChangedEvent(this, null);
            }
        }

        public Dictionary<string, string> GetSettings()
        {
            // Clone the dictionary
            return _settings.ToDictionary(entry => entry.Key, entry => entry.Value);
        }

        /// <summary>
        /// Update the aircraft model for the plugin.
        /// </summary>
        /// <param name="model"></param>
        public void UpdateAircraftModel(AircraftModel model, bool supressEvent)
        {
            _aircraftModel = model;

            if (!supressEvent && OnSimAircraftModelChangedEvent != null)
                OnSimAircraftModelChangedEvent(this, new SimAircraftModelChangedEventArgs(_aircraftModel));
        }

        public override string ToString()
        {
            return Name;
        }
    }
}